package reconhecimento.model;
import java.util.Hashtable;
import java.util.List;

import reconhecimento.excecao.ImagemNulaException;
import reconhecimento.excecao.ImagensTamanhosDiferentesException;
import reconhecimento.util.MatrizConfusao;

public class Reconhecimento {
	private Hashtable<Integer, Padroes> padroes;

	private Testes testes;
	
	public static final byte MENOR_DISTANCIA = 0;
	public static final byte MENOR_MEDIA_DISTANCIA = 1;
	

	public Reconhecimento(final Hashtable<Integer, Padroes> padroes,
			final Testes testes) {
		super();
		this.padroes = padroes;
		this.testes = testes;
	}
	
	public Reconhecimento(final Hashtable<Integer, Padroes> padroes) {
		this(padroes, null);
	}

	public Hashtable<Integer, Padroes> getPadroes() {
		return this.padroes;
	}

	public void setPadroes(final Hashtable<Integer, Padroes> padroes) {
		this.padroes = padroes;
	}

	public Testes getTestes() {
		return this.testes;
	}

	public void setTestes(final Testes testes) {
		this.testes = testes;
	}

	private Integer getSuspeita(final Imagem imagem,byte tipoAlgoritmo) throws ImagensTamanhosDiferentesException, ImagemNulaException {
		Integer suspeita = null;
		int menorDistancia = Integer.MAX_VALUE;
		for (int i = 0; i < 10; i++) {
			final Padroes pads = this.padroes.get(new Integer(i));
			int distancia = 0;
			if(tipoAlgoritmo == MENOR_MEDIA_DISTANCIA){
				distancia = pads.getSomaDistancia(imagem);
			}else if(tipoAlgoritmo == MENOR_DISTANCIA){
				distancia = pads.getMenorDistancia(imagem);
			}
			if (distancia < menorDistancia) {
				menorDistancia = distancia;
				suspeita = new Integer(i);
			}
		}
		return suspeita;
	}
	
	public MatrizConfusao reconhecer(byte tipoAlgoritmo) {
		try {
			final MatrizConfusao mc = new MatrizConfusao();
			final List<Imagem> imagensPrototipo = this.testes.getImagens();
			for (int i = 0; i < imagensPrototipo.size(); i++) {
				final Imagem imaProt = imagensPrototipo.get(i);
				final Integer suspeita = this.getSuspeita(imaProt, tipoAlgoritmo);
				mc.inserirValores(imaProt.getValor(), suspeita);
			}
			return mc;
		} catch (ImagensTamanhosDiferentesException e) {
			e.printStackTrace();
		} catch (ImagemNulaException e) {
			e.printStackTrace();
		}
		return null;
	}

	public Integer reconhecer(Imagem imagem, byte tipoAlgoritmo) throws ImagensTamanhosDiferentesException, ImagemNulaException {
		return this.getSuspeita(imagem, tipoAlgoritmo);
	}
}
